// include header files
var crypto = require('crypto');
var message = require('./message');
var database = require('./database');
var fotostring = require('./fotostring');
var codeOperation = require('./code');
var fs = require('fs');
var util = require('util');

// connect db
database.connectDataBase();

// api signup
exports.signUp = function(request, response) {
	try {
		var result, code;
		
		if (!request.param(fotostring.PARAM)) {
			code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.jsonp(new Array(code, result));
			database.closeDatabase();
			
			return;
		}
		
		var param = JSON.parse(request.param(fotostring.PARAM));

		fotolaDatabase.collection(fotostring.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(error, collection) {
			if (error) {
				code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.jsonp(new Array(code, result));
				database.closeDatabase();
				return;
			}

			if (!param.email || !param.fullName || !param.password) {
				code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.PARAMETER_ERROR;
				if (!param.fullName) {
					result = fotostring.FULL_NAME_MESSAGE + message.MESSAGE_FIELD_NULL_ERROR;
				}else if (!param.email) {
					result = fotostring.EMAIL + message.MESSAGE_FIELD_NULL_ERROR;
				}else if (!param.password) {
					result = fotostring.PASSWORD + message.MESSAGE_FIELD_NULL_ERROR;
				}
				response.jsonp(new Array(code, result));
				database.closeDatabase();
				return;
			}
			collection.findOne({
				"email" : param.email
			}, function(error, cursor) {
				if (cursor) {
					code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
					result = message.MESSAGE_EMAIL_EXIST_ERROR;
					response.jsonp(new Array(code, result));
					database.closeDatabase();
					return;
				} else {
					param.tokenKey = crypto.createHash(fotostring.MD5).update(
							new Date().getTime().toString()).digest(fotostring.HEX);
					console.log(param.tokenKey);
					collection.insert(param, {
						safe : true
					}, function(error, item) {
						if (!error) {
							code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_SUCCESS;
							collection.findOne({
								"email" : param.email
							}, function(error, item) {
								if (item) {
									result = fotostring.TOKEN_KEY + fotostring.EQUAL_OPERATOR + item.tokenKey;
									console.log(result);
									response.jsonp(new Array(code, result));
									database.closeDatabase();
									return;
								}
							});
						}
					});
				}
			});
		});
	} catch (exeption) {
		code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		console.log(exeption.message);
		response.jsonp(new Array(code, result));
		database.closeDatabase();
		return;
	}
}

// api upload avatar
exports.uploadAvatar = function(request, response) {
	try {
		var result, code;

		if (!request.param(fotostring.PARAM)) {
			code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.jsonp(new Array(code, result));
			database.closeDatabase();
			return;
		}

		var param = JSON.parse(request.param(fotostring.PARAM));
		
		if (!param.tokenKey) {
			code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.PARAMETER_ERROR;
			result = fotostring.TOKEN_KEY_MESSAGE +  message.MESSAGE_FIELD_NULL_ERROR;
			response.jsonp(new Array(code, result));
			database.closeDatabase();
			return;
		}
		fotolaDatabase.collection(fotostring.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(error, collection) {
			if (error) {
				code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.jsonp(new Array(code, result));
				database.closeDatabase();
				return;
			}
			
			var tempPath = request.files.avatar.path;
			var savePath = fotostring.AVATAR_PATH + request.files.avatar.name;
			console.log(savePath);
			collection.findOne({"tokenKey":param.tokenKey}, function(error, item){
				if(item){
						
					var is = fs.createReadStream(tempPath)
					var os = fs.createWriteStream(savePath);
					
					try {
						util.pump(is, os, function() {
						    fs.unlinkSync(tempPath);
						});
						database.closeDatabase();
						
					} catch (exeption) {
						code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
						result = message.MESSAGE_UPLOAD_ERROR;
						response.jsonp(new Array(code, result));
						console.log(exeption.message);
						database.closeDatabase();
						return;
					}
				}else{
					code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
					result = message.MESSAGE_UPLOAD_ERROR;
					response.jsonp(new Array(code, result));
					database.closeDatabase();
					return;
				}
			});
			
			collection.update({
				"tokenKey" : param.tokenKey
			}, {
				$set : {
					"avatar": savePath
				}
			}, function(error, item){
				if(!error){
					code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_SUCCESS;
					result = fotostring.EMPTY_STRING;
					response.jsonp(new Array(code, result));
				}
			});
		});
	} catch (exeption) {
		code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		response.jsonp(new Array(code, result));
		database.closeDatabase();
		return;
	}
}

// api login
exports.login = function(request, response) {
	try {
		if (!request.param(fotostring.PARAM)) {
			code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.jsonp(new Array(code, result));
			database.closeDatabase();
			return;
		}

		var result, code;
		var param = JSON.parse(request.param(fotostring.PARAM));

		fotolaDatabase.collection(fotostring.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(error, collection) {
			if (error) {
				code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.jsonp(new Array(code, result));
				database.closeDatabase();
				return;
			}

			if (!param.email || !param.password) {
				code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.PARAMETER_ERROR;
				if (!param.email) {
					result = fotostring.EMAIL + message.MESSAGE_FIELD_NULL_ERROR;

				}else if (!param.password) {
					result = fotostring.PASSWORD + message.MESSAGE_FIELD_NULL_ERROR;
				}
				response.jsonp(new Array(code, result));
				database.closeDatabase();
				return;
			}
			collection.findOne({
				"email" : param.email,
				"password" : param.password
			}, function(error, cursor) {
				if (cursor == null) {
					code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
					result = message.MESSAGE_LOGIN_FAILED_ERROR;
					response.jsonp(new Array(code, result));
					database.closeDatabase();
					return;
				} else {
					var tokenKey = crypto.createHash(fotostring.MD5).update(
							new Date().getTime().toString()).digest(fotostring.HEX);
					collection.update({
						"email" : param.email,
						"password" : param.password
					}, {
						$set : {
							"tokenKey" : tokenKey
						}
					}, function(error, item) {
						if (!error) {
							code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_SUCCESS;
							collection.findOne({
								"email" : param.email,
								"password" : param.password
							}, function(error, item) {
								if (item) {
									result = fotostring.TOKEN_KEY + fotostring.EQUAL_OPERATOR + item.tokenKey;
									response.jsonp(new Array(code, result));
									database.closeDatabase();
									return;
								}
							});
						}
					});
				}
			});
		});
	} catch (exeption) {
		code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		response.jsonp(new Array(code, result));
		database.closeDatabase();
		return;
	}
}

// api logout
exports.logout = function(request, response) {
	try {
		if (!request.param(fotostring.PARAM)) {
			code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.jsonp(new Array(code, result));
			database.closeDatabase();
			return;
		}

		var result, code;
		var param = JSON.parse(request.param(fotostring.PARAM));

		fotolaDatabase.collection(fotostring.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(error, collection) {
			if (error) {
				code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.jsonp(new Array(code, result));
				database.closeDatabase();
				return;
			}

			if (!param.tokenKey) {
				code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.PARAMETER_ERROR;
				result = fotostring.TOKEN_KEY_MESSAGE + message.MESSAGE_FIELD_NULL_ERROR;
				response.jsonp(new Array(code, result));
				database.closeDatabase();
				return;
			}
			collection.findOne({
				"tokenKey" : param.tokenKey
			}, function(error, cursor) {

				if (!cursor) {
					code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
					result = message.MESSAGE_UNEXPECTED_ERROR;
					response.jsonp(new Array(code, result));
					database.closeDatabase();
					return;
				} else {
					collection.update({
						"tokenKey": param.tokenKey
					}, {
						$set : {
							"tokenKey" : fotostring.EMPTY_STRING
						}
					}, function(error, item) {
						if (!error) {
							code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_SUCCESS;
							result = fotostring.EMPTY_STRING;
							response.jsonp(new Array(code, result));
							database.closeDatabase();
							return;
						}
					});
				}
			});
		});
	} catch (exeption) {
		code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		response.jsonp(new Array(code, result));
		database.closeDatabase();
		return;
	}
}

// api update profile
exports.updateProfile = function(request, response) {
	try {
		var result, code;
		
		if (request.param(fotostring.PARAM)) {
			code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
			result = message.MESSAGE_UNEXPECTED_ERROR;
			response.jsonp(new Array(code, result));
			database.closeDatabase();
			return;
		}

		var param = JSON.parse(request.param(fotostring.PARAM));

		fotolaDatabase.collection(fotostring.FOTO_DB_ACCOUNT_TABLE, {
			strict : true
		}, function(error, collection) {
			if (error) {
				code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
				result = message.MESSAGE_DB_ERROR;
				response.jsonp(new Array(code, result));
				database.closeDatabase();
				return;
			}

			if (!param.tokenKey || !param.email || !param.fullName
					|| !param.password) {
				code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.PARAMETER_ERROR;
				if (!param.fullName) {
					result = fotostring.FULL_NAME_MESSAGE + message.MESSAGE_FIELD_NULL_ERROR;
				}else if (!param.email) {
					result = fotostring.EMAIL + message.MESSAGE_FIELD_NULL_ERROR;
				} else if (!param.password) {
					result =fotostring.PASSWORD +  message.MESSAGE_FIELD_NULL_ERROR;
				}else if (!param.tokenKey) {
					result = fotostring.TOKEN_KEY_MESSAGE + message.MESSAGE_FIELD_NULL_ERROR;
				}
				response.jsonp(new Array(code, result));
				database.closeDatabase();
				return;
			}

			collection.findOne({
				"tokenKey" : param.tokenKey
			}, function(error, cursor) {
				if (!cursor) {
					code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
					result = message.MESSAGE_UNEXPECTED_ERROR;
					response.jsonp(new Array(code, result));
					database.closeDatabase();
					return;
				} else {
					collection.findOne({
						"email" : param.email
					}, function(error, cursor) {
						if (cursor) {
							code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
							result = message.MESSAGE_EMAIL_EXIST_ERROR;
							response.jsonp(new Array(code, result));
							database.closeDatabase();
							return;
						} else {
							collection.update({
								"tokenKey" : param.tokenKey
							}, {
								$set : {
									"email" : param.email,
									"password" : param.password,
									"fullName" : param.fullName
								}
							}, function(error, item) {
								if (!error) {
									code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_SUCCESS;
									result = fotostring.EMPTY_STRING;
									response.jsonp(new Array(code, result));
									database.closeDatabase();
									return;
								}
							});
						}
					});
				}
			});
		});
	} catch (exeption) {
		code = fotostring.CODE + fotostring.EQUAL_OPERATOR + codeOperation.OPERATION_ERROR;
		result = message.MESSAGE_UNEXPECTED_ERROR;
		response.jsonp(new Array(code, result));
		database.closeDatabase();
		return;
	}
}
